﻿namespace LiSAClient.WpfClient.Utils
{
    using System.Windows;

    using LiSAClient.Core.Messages;
    using LiSAClient.WpfClient.View.Frame;
    using LiSAClient.WpfClient.View.Frame.Windows;
    using LiSAClient.WpfClient.ViewModel.Frame.Windows;

    using GalaSoft.MvvmLight.Messaging;
    using GalaSoft.MvvmLight.Threading;

    using DetachedWindow = LiSAClient.WpfClient.View.Frame.Windows.DetachedWindow;
    using MainWindow = LiSAClient.WpfClient.View.Frame.Windows.MainWindow;
    using NotificationPopup = LiSAClient.WpfClient.View.Frame.Windows.NotificationPopup;

    /// <summary>
    /// Used for handling opening and closing of windows.
    /// Handles all window related messages sent through the system, such that we can always perform the wanted actions on a window.
    /// </summary>
    public class WindowHandler
    {
        public WindowHandler()
        {
            Messenger.Default.Register<ShowContentInWindowMessage>(this, this.Handle);
            Messenger.Default.Register<ShowMainWindowMessage>(this, this.Handle);
            Messenger.Default.Register<ShowNotificationMessage>(this, this.Handle);
            Messenger.Default.Register<ShowLoadingContentMessage>(this, this.Handle);
        }

        /// <summary>
        /// Creates a new window, which just displays the <see cref="Wait"/> usercontrol.
        /// </summary>
        /// <param name="message">The message with the OnPresented method that should be run in this new window.</param>
        private void Handle(ShowLoadingContentMessage message)
        {
            if (message.Content == null)
            {
                return;
            }

            var content = message.Content;

            DispatcherHelper.CheckBeginInvokeOnUI(() =>
            {
                var newWindow = new LoadingWindow { Owner = Application.Current.MainWindow };
                var windowViewModel = new DetachedWindowViewModel(content.Title);
                content.SetPresenter(windowViewModel);
                content.ShowInWindow = false;
                windowViewModel.PresentContent(content, false);
                newWindow.DataContext = windowViewModel;
                content.ShowInWindow = true;
                newWindow.Loaded += (s, e) => message.Content.OnPresented();
                newWindow.Show();
            });
        }

        /// <summary>
        /// Creates the primary <see cref="MainWindowViewModel"/>/<see cref="MainWindow"/>. Used during startup and logout.
        /// </summary>
        /// <param name="message">The message.</param>
        private void Handle(ShowMainWindowMessage message)
        {
            var mainWindowViewModel = new MainWindowViewModel();
            var mainWindow = new MainWindow { DataContext = mainWindowViewModel };
            mainWindow.Show();
        }

        /// <summary>
        /// Creates a new <see cref="DetachedWindowViewModel"/>/<see cref="DetachedWindow"/>, and runs the OnPresented.
        /// </summary>
        /// <param name="message">The message containing the content.</param>
        private void Handle(ShowContentInWindowMessage message)
        {
            if (message.Content == null)
            {
                return;
            }

            var content = message.Content;

            DispatcherHelper.CheckBeginInvokeOnUI(() =>
            {
                var newWindow = new DetachedWindow();
                //var newWindow = new DetachedWindow { Owner = Application.Current.MainWindow };
                var windowViewModel = new DetachedWindowViewModel(content.Title);
                content.SetPresenter(windowViewModel);
                content.ShowInWindow = false;
                windowViewModel.PresentContent(content, false);
                newWindow.DataContext = windowViewModel;
                content.ShowInWindow = true;

                if (message.OnLoadedAction != null)
                {
                    newWindow.Loaded += (s, e) => message.OnLoadedAction();
                }
                else
                {
                    newWindow.Loaded += (s, e) => message.Content.OnPresented();
                }

                newWindow.Show();
            });
        }

        /// <summary>
        /// Creates a modal <see cref="NotificationPopupViewModel"/>/<see cref="NotificationPopup"/>, showing the information registered in the message.
        /// </summary>
        /// <param name="msg">The message.</param>
        private void Handle(ShowNotificationMessage msg)
        {
            DispatcherHelper.CheckBeginInvokeOnUI(
                () =>
                {
                    var exceptionPopup = new NotificationPopup();
                    var popUp = new NotificationPopupViewModel(msg.Header, msg.Body, msg.NotificationType);
                    exceptionPopup.DataContext = popUp;
                    exceptionPopup.ShowDialog();
                });
        }
    }
}
